package com.zzb.codegenerator.generator.table;

import com.zzb.codegenerator.bean.ProjectMeta;
import com.zzb.codegenerator.bean.TableColumn;
import com.zzb.codegenerator.bean.TableMeta;
import com.zzb.codegenerator.config.GeneratorConfig;
import com.zzb.codegenerator.generator.connect.ConnectPool;
import com.zzb.codegenerator.generator.context.TableMetaContext;
import com.zzb.codegenerator.utils.Misc;
import com.zzb.codegenerator.utils.MySQLTypeToJavaType;
import org.apache.commons.collections.CollectionUtils;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by zhangzhenbin on 17-4-5.
 */
public class TableMetaFactoryBean {
    /**
     * 根据命名规范重命名
     */
    private static String rename(String type, String preStr) {
        String str = preStr;
        switch (type) {
            case "NATIVE":
                str = preStr;
                break;
            case "UNDERLINE":
                str = Misc.camelToUnderline(preStr);
                break;
            case "HUMP":
            default:
                str = Misc.underlineToCamel(preStr);
                break;

        }
        return str;
    }

    /**
     * 通过metaData和tableName创建表结构POJO
     *
     * @throws Exception
     */
    public static TableMeta createTableMeta( GeneratorConfig config, String tableName) throws Exception {
        //获取连接
        Connection connection = ConnectPool.getConnection(config.getDriverClassName(), config.getJdbcUrl(), config.getJdbcUsername(), config.getJdbcPassword());
        if (connection == null) throw new Exception("数据库连接失败");


        System.out.println("正在创建 " + tableName + " 的结构类");
        //获取数据库结构
        DatabaseMetaData metaData = connection.getMetaData();
        TableMeta tableMeta = new TableMeta();
        ResultSet primaryKeys = metaData.getPrimaryKeys(null, "%", tableName);
        ResultSet resultSet = metaData.getColumns(null, "%", tableName, "%");
        int row = 0;

        //获取表注释的sql定义
        String tableRemarksSql = "SELECT TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA='" + config.getSchema() + "' AND TABLE_NAME='" + tableName + "'";
        ResultSet tableRemarkRs = connection.createStatement().executeQuery(tableRemarksSql);
        //主键指针指到最后
        tableRemarkRs.last();
        row = tableRemarkRs.getRow();
        //如果有多个抛出异常
        if (row == 0) {
            throw new Exception("ERROR-没有找到对应表..");
        }

        if (row != 1) {
            throw new Exception("ERROR-发现重复表..");
        }
        String tableComment = tableRemarkRs.getString("TABLE_COMMENT");


        //主键指针指到最后
        primaryKeys.last();
        row = primaryKeys.getRow();
        //如果主键只有一个才创建
        if (row == 1) {
            String column_name = primaryKeys.getString("COLUMN_NAME");
            tableMeta.setPrimaryKeyName(column_name);
        } else tableMeta.setPrimaryKeyName(null);


        List<TableColumn> tableColumns = new ArrayList<>();
        while (resultSet.next()) {
            TableColumn column = new TableColumn();
            //字段名
            String column_name = resultSet.getString("COLUMN_NAME");
            column.setColumnName(column_name);
            //字段类型
            String column_type = resultSet.getString("TYPE_NAME");
            column_type = column_type.replace(" UNSIGNED", "");
            column.setColumnType(column_type);
            column.setPropertyType(MySQLTypeToJavaType.mysql2java.get(column_type).getJavaType());
            column.setPropertyFullType(MySQLTypeToJavaType.mysql2java.get(column_type).getJavaFullType());
            column.setPropertyName(rename(config.getNameType(), column_name));
            //字段注释
            String column_comment = resultSet.getString("REMARKS");
            column.setColumnComment(column_comment);
            if (tableMeta.getPrimaryKeyName() != null && column_name.equals(tableMeta.getPrimaryKeyName())) {
                column.setPrimaryKey(true);
                tableMeta.setPrimaryKeyColumn(column);
            } else {
                column.setPrimaryKey(false);
            }
            tableColumns.add(column);
        }

        tableMeta.setConfig(config);
        tableMeta.setTableName(tableName);
        tableMeta.setBeanName(TableMetaContext.getTableMap().get(tableName));
        tableMeta.setTableComment(tableComment);
        tableMeta.setTableColumns(tableColumns);
        return tableMeta;
    }

    /***
     * 获取tableMeta列表
     */
    public static List<TableMeta> createTableMetaList(GeneratorConfig config)  throws Exception {
        //初始化TableMetaContext
        Map<String, String> tableMap = TableMetaContext.initAndGetTableMap(config);
        List<TableMeta> tableMetas = new ArrayList<>();
        //遍历要生成的表
        for (String table : tableMap.keySet()) {
            //通过metaData和tableName创建表结构POJO
            tableMetas.add(  TableMetaFactoryBean.createTableMeta( config, table));
        }
        return tableMetas;
    }

    /***
     * 获取projectMeta列表
     */
    public static List<ProjectMeta> createProjectMetaList(GeneratorConfig config) throws Exception{
        List<TableMeta> tableMetas = createTableMetaList(config);
        return tableMetas.stream().map(tableMeta -> {
            ProjectMeta projectMeta = new ProjectMeta();
            projectMeta.setGeneratorConfig(config);
            projectMeta.setTableMeta(tableMeta);
            return projectMeta;
        }).collect(Collectors.toList());
    }
}
